// 导入 axios 库，用于发送 HTTP 请求
import axios from 'axios';

// 从 Element Plus 库中导入 ElMessage 和 ElMessageBox 组件，用于显示提示信息和对话框
import { ElMessage, ElMessageBox } from 'element-plus';

// 从 Pinia 存储中导入 basic store，用于管理全局状态
import { useBasicStore } from '@/store/basic';

// 创建 axios 请求实例
const service = axios.create({
    baseURL: import.meta.env.VITE_APP_BASE_URL, // 设置基础 URL，从环境变量中获取
    timeout: 12000 // 设置请求超时时间为 12000 毫秒
});

let loadingInstance = null; // 用于存储 loading 提示实例
let tempReqUrlSave = ''; // 临时保存请求 URL
let authorTipDoor = true; // 控制授权提示的开关

// 定义一个函数，用于处理未授权的情况
const noAuthDill = () => {
    authorTipDoor = false; // 关闭授权提示开关
    ElMessageBox.confirm('请重新登录', {
        confirmButtonText: '重新登录',
        closeOnClickOverlay: false,
        showCancelButton: false,
        showClose: false,
        type: 'warning'
    }).then(() => {
        useBasicStore().resetStateAndToLogin(); // 重置状态并跳转到登录页面
        authorTipDoor = true; // 重新打开授权提示开关
    });
};

// 请求前拦截器
service.interceptors.request.use(
    (req) => {
        const { token, axiosPromiseArr } = useBasicStore();
        // 收集请求地址，用于取消请求
        req.cancelToken = new axios.CancelToken((cancel) => {
            tempReqUrlSave = req.url;
            axiosPromiseArr.push({
                url: req.url,
                cancel
            });
        });

        // 设置 token 到请求头
        if (token) req.headers['X-Auth-Token'] = token;

        // 如果请求方法是 GET 并且没有 params，使用 data 作为 params
        if (req.method?.toLowerCase() === 'get' && !req.params) req.params = req.data;

        // 请求加载提示
        if (req.reqLoading ?? true) {
            loadingInstance = ElMessage.loading({
                message: '数据载入中...',
                duration: 0,
                background: 'rgba(0, 0, 0, 0.7)'
            });
        }

        console.log('Request:', req); // 添加请求日志

        return req;
    },
    (err) => {
        console.error('Request Error:', err); // 添加请求错误日志
        return Promise.reject(err);
    }
);

// 请求后拦截器
service.interceptors.response.use(
    (res) => {
        // 取消请求
        useBasicStore().remotePromiseArrByReqUrl(tempReqUrlSave);
        if (loadingInstance) {
            loadingInstance.close(); // 清除 loading 提示
        }

        // 处理文件下载
        if (res.data?.type?.includes("sheet")) {
            return res;
        }

        const { code, msg } = res.data;
        const successCode = [0, 200, 20000]; // 成功状态码
        const noAuthCode = [401, 403]; // 未授权状态码

        if (successCode.includes(code)) {
            console.log('Response:', res); // 添加响应日志
            return res.data;
        } else {
            // authorTipDoor 防止多个请求多次提示
            if (authorTipDoor) {
                if (noAuthCode.includes(code)) {
                    noAuthDill(); // 处理未授权情况
                } else {
                    if (!res.config?.isNotTipErrorMsg) {
                        ElMessage.error({
                            message: msg || '请求失败',
                            duration: 2 * 1000
                        });
                    } else {
                        return res;
                    }
                    return Promise.reject(msg || '请求失败');
                }
            }
        }
    },
    (err) => {
        // 取消请求
        useBasicStore().remotePromiseArrByReqUrl(tempReqUrlSave);
        if (loadingInstance) {
            loadingInstance.close(); // 清除 loading 提示
        }

        console.error('Response Error:', err); // 添加响应错误日志

        ElMessage.error({
            message: err.message || '网络请求失败',
            duration: 2 * 1000
        });

        return Promise.reject(err);
    }
);

// 手动取消请求
export function cancelRequest(url) {
    const { axiosPromiseArr } = useBasicStore();
    const index = axiosPromiseArr.findIndex(item => item.url === url);
    if (index !== -1) {
        axiosPromiseArr[index].cancel(); // 取消请求
        axiosPromiseArr.splice(index, 1); // 从数组中移除已取消的请求
    }
}

// 导出 service 实例给页面调用，config -> 页面的配置
export default function axiosReq(config) {
    return service(config);
}
